package domino;

import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;


class PanelDropTarget implements DropTargetListener {

    protected JPanel pane;
    private boolean habilitado;
    protected DropTarget dropTarget;
    protected boolean acceptableType;
    protected DataFlavor targetFlavor;
    private ConectorJuego conector;
    private Tren tren;
    private Ficha motor;
    private final frmDomino parent;

    public boolean getHabilitado() {  return habilitado;  }
    public void setHabilitado(boolean value) { habilitado = value; }
    
    public ConectorJuego getConector() {  return conector; }
    public void setConector(ConectorJuego value) { conector = value; }
    
    public Tren getTren() {return tren;}
    public void setTren(Tren value) { tren = value; }
    
    public Ficha getMotor() { return motor; }
    public void setMotor(Ficha value) { motor = value; }

    public PanelDropTarget(JPanel pane, frmDomino parent) {
        this.pane = pane;
        this.parent = parent;
        dropTarget = new DropTarget(pane, DnDConstants.ACTION_COPY_OR_MOVE, this, true, null);
    }

    public void dragEnter(DropTargetDragEvent dtde) {
        checkTransferType(dtde);
        acceptOrRejectDrag(dtde);
    }

    public void dragExit(DropTargetEvent dte) {
    }

    public void dragOver(DropTargetDragEvent dtde) {
        acceptOrRejectDrag(dtde);
    }

    public void dropActionChanged(DropTargetDragEvent dtde) {
        acceptOrRejectDrag(dtde);
    }

    public void drop(DropTargetDropEvent dtde) {
        if ((dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0) {
            dtde.acceptDrop(dtde.getDropAction());
            Transferable transferable = dtde.getTransferable();

            try {
                boolean result = dropComponent(transferable);
                dtde.dropComplete(result);
            } catch (Exception e) {
                dtde.dropComplete(false);
            }
        } else {
            dtde.rejectDrop();
        }
    }

    protected boolean acceptOrRejectDrag(DropTargetDragEvent dtde) {

        int dropAction = dtde.getDropAction();
        int sourceActions = dtde.getSourceActions();
        boolean acceptedDrag = false;

        if (!acceptableType || (sourceActions & DnDConstants.ACTION_COPY_OR_MOVE) == 0) {
            dtde.rejectDrag();
        } else if ((dropAction & DnDConstants.ACTION_COPY_OR_MOVE) == 0) {
            dtde.acceptDrag(DnDConstants.ACTION_COPY);
            acceptedDrag = true;
        } else {
            dtde.acceptDrag(dropAction);
            acceptedDrag = true;
        }
        return acceptedDrag;
    }

    protected void checkTransferType(DropTargetDragEvent dtde) {
        acceptableType = false;
        DataFlavor[] fl = dtde.getCurrentDataFlavors();
        for (int i = 0; i < fl.length; i++) {
            Class dataClass = fl[i].getRepresentationClass();
            if (Component.class.isAssignableFrom(dataClass)) {
                targetFlavor = fl[i];
                acceptableType = true;
                break;
            }
        }
    }

    protected boolean dropComponent(Transferable transferable) throws IOException, UnsupportedFlavorException {
        if (habilitado) {
            Object o = transferable.getTransferData(targetFlavor);
            if (o instanceof FichaBoton) {
                boolean aceptar = false;
                FichaBoton dropped = (FichaBoton) o;
                int fichas = pane.getComponentCount();
                if (fichas > 0) {
                    FichaBoton ultima = (FichaBoton) pane.getComponent(fichas - 1);
                    if (ultima.getFicha().getDerecha() == dropped.getFicha().getIzquierda()) {
                        aceptar = true;
                    }
                } 
                else if(motor.getDerecha() == dropped.getFicha().getIzquierda()){
                    aceptar = true;
                }
                if (aceptar) {
                    Ficha ficha = dropped.getFicha();                    
                    conector.PonerFicha(tren, ficha);
                    if(!ficha.esPar()){
                        parent.terminarTurno();
                    }
                    pane.add(dropped);
                    pane.validate();
                    return true;
                }
            }
        }
        return false;
    }
}

class DnDUtils {

    public static String showActions(int action) {
        String actions = "";
        if ((action & (DnDConstants.ACTION_LINK | DnDConstants.ACTION_COPY_OR_MOVE)) == 0) {
            return "None";
        }

        if ((action & DnDConstants.ACTION_COPY) != 0) {
            actions += "Copy ";
        }

        if ((action & DnDConstants.ACTION_MOVE) != 0) {
            actions += "Move ";
        }

        if ((action & DnDConstants.ACTION_LINK) != 0) {
            actions += "Link";
        }

        return actions;
    }

    public static boolean isDebugEnabled() {
        return debugEnabled;
    }

    public static void debugPrintln(String s) {
        if (debugEnabled) {
            System.out.println(s);
        }
    }
    private static boolean debugEnabled = (System.getProperty("DnDExamples.debug") != null);
}